
use std::error::Error;
use std::net::SocketAddr;
use std::time::Duration;
use rand::Rng;
use serde::{Deserialize, Serialize};
use socket2::{Domain, SockAddr, Socket, Type};
use tokio::net::{TcpListener, TcpStream};
use tokio::io::{copy_bidirectional as data_forward, AsyncReadExt, AsyncWriteExt};
use tokio::time::sleep;
use tracing::{error, info};
use crate::config::Config;
use crate::data::{Data, DataType};
use crate::{data, get_addr_v6};

fn get_port() -> usize{
    rand::rng().random_range(50000..60000)
}

async fn listener_handle(listener:TcpListener) -> Result<(),Box<dyn Error>>{
    loop {
        let (mut stream, addr) = listener.accept().await?;
        info!("客户端连接：{}", addr);
        tokio::spawn(async move{
            match TcpStream::connect("localhost:9988").await {
                Ok(mut remote) => {
                    info!("本地连接已建立，准备转发");
                    if let Err(e) = data_forward(&mut stream,&mut remote).await{
                        error!("端口转发错误{e}");
                        return;
                    }
                }
                Err(e) => {
                    error!("本地连接建立失败：{e}")
                }
            };

        });
    }
}

async fn get_provider_ip(mut stream:TcpStream) -> Result<String,Box<dyn Error>>{
    let mut buf = [0;512];
    let len = stream.read(&mut buf).await?;
    let addr = String::from_utf8_lossy(&buf[0..len]);
    Ok(addr.to_string())
}
async fn handle_stream(mut local:TcpStream,config: Config) -> Result<(),Box<dyn Error>>{
    // let service_addr = "[::1]:7979";
    let service_addr = get_addr_v6(&config.server.address, config.server.port).await?;
    let mut stream = TcpStream::connect(service_addr).await?;
    info!("连接服务端成功");
    data::set_auth(&mut stream,&config).await;
    let addr = get_provider_ip(stream).await?;
    info!("获取provider ip：{addr}");

    if(addr == "NULL"){
        return Err(Box::from("provider 不存在"));
    }

    let mut remote = TcpStream::connect(addr).await?;
    info!("与provider建立连接，开始数据转发");
    data_forward(&mut local,&mut remote).await?;
    Ok(())
}

async fn run(config: Config) -> Result<(),Box<dyn Error>>{
    // let local_addr = "localhost:6001";
    let local_addr = format!("{}:{}",config.client.bind_addr,config.client.bind_port);
    info!("本地端口监听在：{local_addr}");
    let listener = TcpListener::bind(local_addr).await?;
    loop{
        let (stream,_) = listener.accept().await?;
        info!("有客户端连接");
        let config_clone = config.clone();
        tokio::spawn(async move{
            if let Err(e) = handle_stream(stream,config_clone).await{
                error!("handle_stream err :{e}")
            }
        });
    }

}

pub async fn start(config: Config){
    if let Err(e) = run(config).await{
        error!("start err:{e}")
    }
}
